
#include <QtCore>

#include "geometry/sphere.h"

bool Sphere::intersection(const Sphere& rkA, const Sphere& rkB, QVector3D* pkContact)
{
    qreal distanceSquared = (rkA.center() - rkB.center()).lengthSquared();
    qreal thresholdSquared = qPow(rkA.radius() + rkB.radius(), 2);

    // No collision.
    if(distanceSquared > thresholdSquared)
    {
        if(pkContact)
            pkContact = NULL;

        return false;
    }

    // Collision detected, compute contact point if requested.
    if(pkContact)
        *pkContact = (rkB.center() - rkA.center()) / 2 + rkA.center();

    return true;
}

Sphere::Sphere(void* pkUserData)
    : m_Radius(0),
      m_pkUserData(pkUserData)
{
}

Sphere::Sphere(const QVector3D &rkCenter, qreal radius, void* pkUserData)
    : m_kCenter(rkCenter),
      m_Radius(radius),
      m_pkUserData(pkUserData)
{
}

Sphere::Sphere(qreal x, qreal y, qreal z, qreal radius, void* pkUserData)
    : m_kCenter(x, y, z),
      m_Radius(radius),
      m_pkUserData(pkUserData)
{
}

Sphere::~Sphere()
{
}

Sphere::Sphere(const Sphere& rkOther)
{
    if(&rkOther == this)
        return;

    m_kCenter = rkOther.m_kCenter;
    m_Radius = rkOther.m_Radius;
    m_pkUserData = rkOther.m_pkUserData;
}

Sphere& Sphere::operator = (const Sphere& rkOther)
{
    if(&rkOther == this)
        return *this;

    m_kCenter = rkOther.m_kCenter;
    m_Radius = rkOther.m_Radius;
    m_pkUserData = rkOther.m_pkUserData;

    return *this;
}

bool Sphere::isValid() const
{
    return m_Radius > 0;
}

qreal Sphere::x() const
{
    return m_kCenter.x();
}

qreal Sphere::y() const
{
    return m_kCenter.y();
}

qreal Sphere::z() const
{
    return m_kCenter.z();
}

QVector3D Sphere::center() const
{
    return m_kCenter;
}

qreal Sphere::radius() const
{
    return m_Radius;
}

void Sphere::setPosition(const QVector3D& rkCenter)
{
    m_kCenter = rkCenter;
}

void Sphere::setRadius(qreal kRadius)
{
    m_Radius = kRadius;
}

void* Sphere::userData() const
{
    return m_pkUserData;
}

void Sphere::setUserData(void* pkUserData)
{
    m_pkUserData = pkUserData;
}
